package com.zx.scp.service.impl;


import com.zx.jd.util.JsonUtils;
import com.zx.map.utils.*;
import com.zx.map.wx.WxOauthHelper;
import com.zx.platform.utils.DateUtils;
import com.zx.platform.utils.HttpClientCommon;
import com.zx.platform.utils.HttpParamsUtils;
import com.zx.platform.utils.TmDateUtil;
import com.zx.scp.service.IIncomeService;
import com.zx.scp.service.IncomHandleService;
import com.zx.scp.service.model.OrderPayCallBackModel;
import com.zx.scp.service.model.YintongPayRequestModel;
import com.zx.scp.service.util.swift.MD5;
import com.zx.scp.service.util.swift.SignUtils;
import com.zx.scp.service.util.swift.XmlUtils;
import com.zx.scp.utils.PropertyUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by bibei on 2017/6/2.
 * 51mayun支付
 */
@Service
public class MayunPayIncomeServiceImpl implements IIncomeService {
	private Logger logger = Logger.getLogger(MayunPayIncomeServiceImpl.class);
	@Autowired
	private IncomHandleService incomHandleService;

	/**
	 * 微信 公众号支付
	 *
	 * @param request
	 * @param yintongPayRequestModel
	 * @return
	 * @throws Exception
	 */
	@Override
	public Map winxinJsPay(HttpServletRequest request, YintongPayRequestModel yintongPayRequestModel) throws Exception {
		//获取支付信息
		Map paramMap = initReqParams(request, yintongPayRequestModel);
		paramMap.put("service", "pay.weixin.jspay");
		paramMap.put("body", "微信付款");
		paramMap.put("openId", yintongPayRequestModel.getOpenId());
		paramMap.put("isRaw", "1");
		paramMap.put("appId", WxOauthHelper.APPID);
		paramMap.put("callbackUrl", "http://116.62.116.58:8080/scp/income/mayunpay/nofityPay");

		addSign(paramMap);
		Map<String, Object> resultMap = new HttpClientCommon().getResult(Map.class, PropertyUtil.getValue("mayun_req_url"), paramMap);
		boolean isSuccess = validateResultMap(resultMap);
		if (isSuccess) {
			Map payInfoMap = (Map) resultMap.get("data");
			//String codeUrl = PropertyUtil.getValue("mayun_jspay_url") + "?" + HttpParamsUtils.buildPayParams(JsonUtils.jsonToBean((String) payInfoMap.get("payInfo"),Map.class));//转换支付链接url
			payInfoMap.put("codeUrl", payInfoMap.get("codeUrl"));
			return CommonResponseUtils.successResponse(SUConstants.MSG_SUCCESS_VALUE, payInfoMap);
		} else {
			return CommonResponseUtils.failureResponse(resultMap.get("message"));
		}
	}


	/**
	 * 获取支付信息
	 *
	 * @return
	 */
	@Override
	public Map startPay(HttpServletRequest request, YintongPayRequestModel yintongPayRequestModel) throws Exception {
		//获取支付信息
		try {
			Map paramMap = initReqParams(request, yintongPayRequestModel);
			if (yintongPayRequestModel.getPayType().equals(SUConstants.paymentTypeWX)) {
				paramMap.put("service", "pay.weixin.native");
				paramMap.put("body", "微信付款");
			} else {
				paramMap.put("service", "pay.alipay.native");
				paramMap.put("body", "支付宝付款");
			}
			addSign(paramMap);
			String str = new HttpClientCommon().getResultByPost(PropertyUtil.getValue("mayun_req_url"), paramMap);
			logger.debug("51码云支付请求返回参数：" + str);  //
			Map<String, Object> resultMap = JsonUtils.jsonToBean(str, Map.class);
			if ("1".equals(resultMap.get("status"))) {
				Map<String, String> dataInfo = (Map<String, String>) resultMap.get("data");
				if (SignUtils.checkParam(dataInfo, PropertyUtil.getValue("mayun_mer_key"))) {
					Map orderResult = new HashMap();
					orderResult.put("codeUrl", dataInfo.get("codeUrl"));
					orderResult.put("codeImgUrl", dataInfo.get("codeImgUrl"));
					return CommonResponseUtils.successResponse(orderResult);
				}
			}
			return CommonResponseUtils.failureResponse((String) resultMap.get("message"));
		} catch (Exception e) {
			logger.debug("51码云获取支付异常", e);
			return CommonResponseUtils.failureResponse(SUConstants.SERVER_ERROR);
		}
	}

	/**
	 * 收款通知处理
	 */
	@Override
	public Map payNotify(Map resultMap) {
		if (SignUtils.checkParam(resultMap, PropertyUtil.getValue("mayun_mer_key"))) {
			OrderPayCallBackModel orderPayCallBackModel = new OrderPayCallBackModel();
			transModel(resultMap, orderPayCallBackModel);
			incomHandleService.handleOrderCallBack(orderPayCallBackModel);
			return CommonResponseUtils.successResponse("success");
		} else {
			logger.debug("51码云订单通知 验证签名不通过");
		}
		return CommonResponseUtils.failureResponse((String) resultMap.get("message"));
	}

	/**
	 * 转换订单信息
	 *
	 * @param map
	 * @param orderPayCallBackModel
	 */
	private void transModel(Map map, OrderPayCallBackModel orderPayCallBackModel) {
		orderPayCallBackModel.setOrdId((String) map.get("outTradeNo"));
		orderPayCallBackModel.setPaymentAmt(new BigDecimal((String) map.get("totalFee")).doubleValue());
		orderPayCallBackModel.setPaymentId((String) map.get("tradeNo"));
		orderPayCallBackModel.setPaymentTime((String) map.get("payTime"));
		String result = (String) map.get("payStatus");
		orderPayCallBackModel.setTransStatus("1".equals(result) ? "S" : "F");
	}

	/**
	 * 添加签名
	 *
	 * @param paramMap
	 */
	private void addSign(Map paramMap) {
		String preStr = HttpParamsUtils.buildPayParams(paramMap, false, true);
		logger.debug("51码云加密前:" + preStr);
		String sign = MD5.sign(preStr, "&key=" + PropertyUtil.getValue("mayun_mer_key"), "utf-8");
		paramMap.put("sign", sign);
	}

	/**
	 * 初始化公用参数
	 *
	 * @param request
	 * @param yintongPayRequestModel
	 * @return
	 */
	private Map initReqParams(HttpServletRequest request, YintongPayRequestModel yintongPayRequestModel) {
		int orderEffectiveTime = Integer.valueOf(PropertyUtil.getValue("order_effective_time"));
		Map paramMap = new HashMap<String, String>();
		paramMap.put("version", "1.0");
		paramMap.put("charset", "UTF-8");
		paramMap.put("signType", "MD5");
		paramMap.put("mchCode", PropertyUtil.getValue("mayun_mer_id"));
		paramMap.put("outTradeNo", yintongPayRequestModel.getOrderId());
		paramMap.put("totalFee", yintongPayRequestModel.getAmount());
		paramMap.put("mchCreateIp", IPMacUtils.getIpAddr(request));
		paramMap.put("notifyUrl", PropertyUtil.getValue("mayun_notify_url"));
		paramMap.put("nonceStr", TmDateUtil.nowTime(TmDateUtil.TIMESTAMP_FOMART_OTHER) + RandomStringUtils.random(4, true, true));
		if (orderEffectiveTime > 0) {
			paramMap.put("timeStart", DateFormatUtils.format(new Date(), DateUtils.DATE_TIME_FMT_OTHER));
			paramMap.put("timeExpire", DateFormatUtils.format(TmDateUtil.addHours(new Date(), orderEffectiveTime), DateUtils.DATE_TIME_FMT_OTHER));
		}
		return paramMap;
	}


	/**
	 * 验证返回的数据合法性，并验签
	 *
	 * @param resultMap
	 * @return
	 */
	private boolean validateResultMap(Map resultMap) {
		String status = (String) resultMap.get("status");
		return SUConstants.CODE_SUCCESS_VALUE.equals(status) ? true : false;
	}
}
